﻿

using CheccCoverplateCulvertAssemble.Conmmon;
using CheccCoverplateCulvertAssemble.Entity;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Data;
using System.Runtime.InteropServices.ComTypes;
using System.Text.RegularExpressions;

namespace CheccCoverplateCulvertAssemble.Rebar;

public class Rebar_90Degrees : RebarBase
{
    private readonly double m_lengthOfHook = 0.0;

    public Rebar_90Degrees(ConstructingEntity constructingEntity, string rebarGroupNumber, double diameter, string grades, RebarType rebarType, CurveVector baseLine, double lengthOfHook, double hookDiameter, double startRotationAngle = 0, double endRotationAngle = 0)
        : base(constructingEntity, rebarGroupNumber, diameter, grades, rebarType, baseLine, hookDiameter, startRotationAngle, endRotationAngle)
    {
        this.m_lengthOfHook = lengthOfHook;
    }
    public override CurveVector CreateGuideLineOfRebar()
    {
        ComplexStringElement retComplexString = new(Session.Instance.GetActiveDgnModel(), null);
        #region 基线除去弯钩部分,剩余曲线
        var (curveElements, startPoint, endPoint, startTangentVector, endTangentVector)
            = CulvertHelpers.GetElementsByStartAndEndFractionFromCurveVector(this.BaseLine, (this.HookDiameter + this.Diameter) * 0.5);

        #endregion

        #region 起点弯钩
        var startArcAndLine = this.CreateStartHookLine((DPoint3d)startPoint!, (DVector3d)startTangentVector!);
        #endregion

        #region 终点弯钩
        var endArcAndLine = this.CreateEndHookLine((DPoint3d)endPoint, (DVector3d)endTangentVector);
        #endregion
        retComplexString.AddComponentElement(startArcAndLine.lineOfHook);
        retComplexString.AddComponentElement(startArcAndLine.arcOfHook);
        for (int i = 0; i < curveElements.Count; i++)
        {
            retComplexString.AddComponentElement(curveElements[i]);
        }
        retComplexString.AddComponentElement(endArcAndLine.arcOfHook);
        retComplexString.AddComponentElement(endArcAndLine.lineOfHook);
        CurveVector retCurves = CurvePathQuery.ElementToCurveVector(retComplexString);
        //Element element = DraftingElementSchema.ToElement(Session.Instance.GetActiveDgnModel(), retCurves, null);
        //retComplexString.AddToModel();
        return retCurves;
    }


    public override List<(string standardName, string standValue)> CreateStandardECProperty()
    {
        string rebarJsonFilePath =
            System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) +
            @"\rebarConfig.json";
        List<(string standardName, string standValue)> ret = new();
        var cv = this.CreateGuideLineOfRebar();
        var rebarVolume = cv.SumOfLengths() / GeneralHelpers.UorToMeters * Math.PI *
                          Math.Pow(0.5 * this.Diameter * 0.001, 2);
        var rebarLength = cv.SumOfLengths() / GeneralHelpers.UorToMeters;
        ret.Add(("componentName", this._constructingEntity.ToString()));
        ret.Add(("rebarGroup", this.RebarGroupNumber));
        ret.Add(("rebarDiameter", this.Diameter.ToString()));
        ret.Add(("rebarVolume", rebarVolume.ToString()));
        ret.Add(("rebarType", this.RebarType == RebarType.Ribbed ? "带肋" : "光圆"));
        ret.Add(("rebarGrade", this.Grades));
        ret.Add(("rebarLength", rebarLength.ToString()));
        ret.Add(("weightPerMeter", GeneralHelpers.GetWeightPerMeterOfRebar(this.Grades, this.Diameter, rebarJsonFilePath).ToString()));
        ret.Add(("rebarHookLength", this.m_lengthOfHook.ToString()));
        ret.Add(("rebarHookDiameter", this.HookDiameter.ToString()));
        return ret;
    }

    private (LineElement lineOfHook, ArcElement arcOfHook) CreateStartHookLine(DPoint3d uorLocate, DVector3d pathDir)
    {
        double radius = (this.HookDiameter + this.Diameter) * 0.5 * 0.001 * GeneralHelpers.UorToMeters;
        double hookLength = this.m_lengthOfHook * 0.01 * GeneralHelpers.UorToMeters;
        DPoint3d centerPoint = new(radius, 0, 0);

        #region 弯钩直线部分
        LineElement lineElement = new LineElement(Session.Instance.GetActiveDgnModel(), null,
           new DSegment3d(new DPoint3d(hookLength, -radius, 0), new DPoint3d(radius, -radius, 0)));
        var tempLine = CulvertHelpers.TransformElementRoate90ByXaxis(lineElement, 90);
        var rotateTempLine = CulvertHelpers.TransformElementRoate90ByZaxis(tempLine, -this.StartRotationAngle);
        var hookLine = CulvertHelpers.TransformElementNormaltoPath(rotateTempLine, uorLocate, pathDir);
        #endregion

        #region 弯钩弧部分
        ArcElement arcElement = new ArcElement(Session.Instance.GetActiveDgnModel(), null,
            centerPoint, radius, radius, DMatrix3d.Identity, 1.5 * Math.PI, -Math.PI / 2);
        var tempArc = CulvertHelpers.TransformElementRoate90ByXaxis(arcElement, 90);
        var rotateTempArc = CulvertHelpers.TransformElementRoate90ByZaxis(tempArc, -this.StartRotationAngle);
        var hookArc = CulvertHelpers.TransformElementNormaltoPath(rotateTempArc, uorLocate, pathDir);
        #endregion
        return (hookLine, hookArc);
    }

    private (LineElement lineOfHook, ArcElement arcOfHook) CreateEndHookLine(DPoint3d uorLocate, DVector3d pathDir)
    {
        List<Element> elements = new List<Element>();
        double radius = (this.HookDiameter + this.Diameter) * 0.5 * 0.001 * GeneralHelpers.UorToMeters;
        double hookLength = this.m_lengthOfHook * 0.01 * GeneralHelpers.UorToMeters;
        DPoint3d centerPoint = new(radius, 0, 0);
        #region 弯钩弧部分
        ArcElement arcElement = new ArcElement(Session.Instance.GetActiveDgnModel(), null,
           centerPoint, radius, radius, DMatrix3d.Identity, Math.PI, Math.PI / 2);
        var tempArc = CulvertHelpers.TransformElementRoate90ByXaxis(arcElement, -90);
        var rotateTempArc = CulvertHelpers.TransformElementRoate90ByZaxis(tempArc, -this.EndRotationAngle);
        var hookArc = CulvertHelpers.TransformElementNormaltoPath(rotateTempArc, uorLocate, pathDir);
        #endregion
        #region 弯钩直线部分
        LineElement lineElement = new LineElement(Session.Instance.GetActiveDgnModel(), null,
          new DSegment3d(new DPoint3d(radius, -radius, 0), new DPoint3d(hookLength, -radius, 0)));
        var tempLine = CulvertHelpers.TransformElementRoate90ByXaxis(lineElement, -90);
        var rotateTempLine = CulvertHelpers.TransformElementRoate90ByZaxis(tempLine, -this.EndRotationAngle);
        var hookLine = CulvertHelpers.TransformElementNormaltoPath(rotateTempLine, uorLocate, pathDir);
        #endregion
        return (hookLine, hookArc);
    }
}
